#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
主应用窗口
"""

import pygame
import os
import threading
import tkinter as tk
from tkinter import filedialog
from bilibili_downloader.ui.theme import *
from bilibili_downloader.ui.components import Button, InputBox, LogArea, ProgressBar, get_chinese_font
from bilibili_downloader.downloader.engine import DownloadEngine
from bilibili_downloader.utils.logger import Logger

class App:
    """主应用窗口类"""
    
    def __init__(self):
        """初始化应用"""
        # 初始化pygame
        pygame.init()
        pygame.font.init()
        
        # 创建窗口
        self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
        pygame.display.set_caption("B站视频下载器")
        
        # 设置窗口图标（如果有）
        icon_path = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 
                               "resources", "bilibili_icon.png")
        if os.path.exists(icon_path):
            try:
                icon = pygame.image.load(icon_path)
                pygame.display.set_icon(icon)
            except:
                pass
        
        # 初始化组件
        self._init_components()
        
        # 初始化下载引擎
        self.download_engine = DownloadEngine()
        
        # 初始化日志系统
        self.logger = Logger(self.log_area)
        
        # 下载状态
        self.is_downloading = False
        self.download_thread = None
        
        # 下载路径
        self.download_path = os.path.join(os.path.expanduser("~"), "Downloads")
        self.path_input.text = self.download_path
        
    def _init_components(self):
        """初始化UI组件"""
        # 标题字体
        self.title_font = get_chinese_font(FONT_LARGE)
        self.label_font = get_chinese_font(FONT_MEDIUM)
        
        # 定义垂直间距
        label_to_control_gap = 10  # 标签到控件的间距
        section_gap = 25          # 不同部分之间的间距
        
        # URL输入框（带清空按钮）
        url_label_y = PADDING + 10
        url_input_y = url_label_y + label_to_control_gap + 15  # 标签高度约15
        self.url_input = InputBox(PADDING, url_input_y, WINDOW_WIDTH - 2 * PADDING, INPUT_HEIGHT, 
                                 placeholder="请输入B站视频URL", show_clear_button=True)
        
        # 下载路径输入框和浏览按钮
        path_label_y = url_input_y + INPUT_HEIGHT + section_gap
        path_input_y = path_label_y + label_to_control_gap + 15
        self.path_input = InputBox(PADDING, path_input_y, WINDOW_WIDTH - 120 - 2 * PADDING, INPUT_HEIGHT, 
                                  placeholder="下载路径", show_clear_button=True)
        self.browse_button = Button(WINDOW_WIDTH - PADDING - 100, path_input_y, 100, INPUT_HEIGHT, "浏览")
        
        # 下载和取消按钮
        buttons_y = path_input_y + INPUT_HEIGHT + section_gap
        button_width = 150
        self.download_button = Button((WINDOW_WIDTH - 2 * button_width - 20) // 2, buttons_y, 
                                     button_width, BUTTON_HEIGHT, "开始下载")
        self.cancel_button = Button((WINDOW_WIDTH - 2 * button_width - 20) // 2 + button_width + 20, 
                                   buttons_y, button_width, BUTTON_HEIGHT, "取消下载", color=RED)
        
        # 日志区域
        log_label_y = buttons_y + BUTTON_HEIGHT + section_gap
        log_area_y = log_label_y + label_to_control_gap + 15
        self.log_area = LogArea(PADDING, log_area_y, WINDOW_WIDTH - 2 * PADDING, LOG_HEIGHT)
        
        # 进度条
        progress_label_y = log_area_y + LOG_HEIGHT + section_gap
        progress_bar_y = progress_label_y + label_to_control_gap + 15
        self.progress_bar = ProgressBar(PADDING, progress_bar_y, WINDOW_WIDTH - 2 * PADDING, PROGRESS_HEIGHT)
        
        # 保存各标签的Y坐标，用于绘制
        self.url_label_y = url_label_y
        self.path_label_y = path_label_y
        self.log_label_y = log_label_y
        self.progress_label_y = progress_label_y
        
    def run(self):
        """运行应用程序"""
        self.logger.info("B站视频下载器已启动")
        
        # 测试中文字体
        test_font = get_chinese_font(FONT_MEDIUM)
        test_surface = test_font.render("测试中文显示", True, BLACK)
        if test_surface.get_width() < 50:  # 如果宽度太小，可能没有正确渲染中文
            print("警告：中文字体渲染测试失败，中文可能无法正常显示")
        else:
            print("中文字体渲染测试成功")
            
        # 提示用户如何使用
        self.logger.info("提示：点击输入框激活后可以输入文字")
        self.logger.info("提示：右键点击输入框可以粘贴剪贴板内容")
        
        # 我们将使用tkinter来处理粘贴功能，不再依赖pyperclip
        self.logger.info("提示：使用Ctrl+V粘贴时，请先点击输入框激活它")
        
        running = True
        clock = pygame.time.Clock()
        
        while running:
            # 计算帧率和时间增量
            dt = clock.tick(60) / 1000.0  # 转换为秒
            
            mouse_pos = pygame.mouse.get_pos()
            
            # 处理事件
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                
                # 处理输入框事件
                self.url_input.handle_event(event)
                self.path_input.handle_event(event)
                
                # 处理日志区域滚动
                self.log_area.handle_event(event)
                
                # 处理右键点击（粘贴）
                if event.type == pygame.MOUSEBUTTONDOWN and event.button == 3:  # 右键点击
                    try:
                        # 使用tkinter获取剪贴板内容
                        root = tk.Tk()
                        root.withdraw()  # 隐藏窗口
                        
                        try:
                            clipboard_text = root.clipboard_get()
                            
                            # 检查哪个输入框被点击
                            if self.url_input.rect.collidepoint(event.pos):
                                self.url_input.text = clipboard_text
                                self.url_input.cursor_position = len(clipboard_text)
                                self.url_input.active = True
                                self.path_input.active = False
                                self.logger.info("已粘贴URL")
                            elif self.path_input.rect.collidepoint(event.pos):
                                self.path_input.text = clipboard_text
                                self.path_input.cursor_position = len(clipboard_text)
                                self.path_input.active = True
                                self.url_input.active = False
                                self.logger.info("已粘贴路径")
                        except:
                            self.logger.error("粘贴失败：剪贴板为空或格式不支持")
                        
                        root.destroy()
                    except Exception as e:
                        self.logger.error(f"粘贴错误: {str(e)}")
                
                # 处理按钮点击
                if self.browse_button.is_clicked(event):
                    self._browse_folder()
                
                if self.download_button.is_clicked(event) and not self.is_downloading:
                    self._start_download()
                
                if self.cancel_button.is_clicked(event) and self.is_downloading:
                    self._cancel_download()
            
            # 更新组件状态
            self.url_input.update(dt, mouse_pos)
            self.path_input.update(dt, mouse_pos)
            self.browse_button.update(mouse_pos)
            self.download_button.update(mouse_pos)
            self.cancel_button.update(mouse_pos)
            
            # 绘制界面
            self._draw()
        
        pygame.quit()
    
    def _draw(self):
        """绘制界面"""
        # 填充背景
        self.screen.fill(WHITE)
        
        try:
            # 绘制标题
            title_surface = self.title_font.render("B站视频下载器", True, BLACK)
            self.screen.blit(title_surface, (WINDOW_WIDTH // 2 - title_surface.get_width() // 2, PADDING // 2))
            
            # 绘制URL标签和输入框
            url_label = self.label_font.render("视频URL:", True, BLACK)
            self.screen.blit(url_label, (PADDING, self.url_label_y))
            self.url_input.draw(self.screen)
            
            # 绘制路径标签、输入框和浏览按钮
            path_label = self.label_font.render("下载路径:", True, BLACK)
            self.screen.blit(path_label, (PADDING, self.path_label_y))
            self.path_input.draw(self.screen)
            self.browse_button.draw(self.screen)
            
            # 绘制按钮
            self.download_button.draw(self.screen)
            self.cancel_button.draw(self.screen)
            
            # 绘制日志标签和区域
            log_label = self.label_font.render("下载日志:", True, BLACK)
            self.screen.blit(log_label, (PADDING, self.log_label_y))
            self.log_area.draw(self.screen)
            
            # 绘制进度标签和进度条
            progress_label = self.label_font.render("下载进度:", True, BLACK)
            self.screen.blit(progress_label, (PADDING, self.progress_label_y))
            self.progress_bar.draw(self.screen)
        except Exception as e:
            print(f"绘制界面时出错: {str(e)}")
        
        # 更新显示
        pygame.display.flip()
    
    def _browse_folder(self):
        """打开文件夹选择对话框"""
        # 创建一个临时的tkinter窗口
        root = tk.Tk()
        root.withdraw()  # 隐藏窗口
        
        # 打开文件夹选择对话框
        folder_path = filedialog.askdirectory(initialdir=self.download_path)
        
        # 销毁tkinter窗口
        root.destroy()
        
        # 更新下载路径（只有当用户选择了路径时）
        if folder_path:
            # 避免重复记录
            if folder_path != self.download_path:
                self.download_path = folder_path
                self.path_input.text = folder_path
                self.path_input.cursor_position = len(folder_path)
                self.logger.info(f"已选择下载路径: {folder_path}")
    
    def _start_download(self):
        """开始下载视频"""
        url = self.url_input.text.strip()
        path = self.path_input.text.strip()
        
        if not url:
            self.logger.error("请输入视频URL")
            return
        
        if not path:
            self.logger.error("请选择下载路径")
            return
        
        if not os.path.exists(path):
            try:
                os.makedirs(path)
                self.logger.info(f"创建下载路径: {path}")
            except Exception as e:
                self.logger.error(f"创建下载路径失败: {str(e)}")
                return
        
        self.is_downloading = True
        self.logger.info(f"开始下载: {url}")
        
        # 在新线程中执行下载
        self.download_thread = threading.Thread(
            target=self._download_thread_func,
            args=(url, path)
        )
        self.download_thread.daemon = True
        self.download_thread.start()
    
    def _download_thread_func(self, url, path):
        """下载线程函数"""
        try:
            self.download_engine.download(url, path, self._update_progress, self.logger)
            if not self.download_engine.is_cancelled:
                self.logger.success("下载完成")
        except Exception as e:
            self.logger.error(f"下载失败: {str(e)}")
        finally:
            self.is_downloading = False
    
    def _cancel_download(self):
        """取消下载"""
        if self.is_downloading:
            self.download_engine.cancel()
            self.logger.info("正在取消下载...")
    
    def _update_progress(self, progress):
        """更新进度条"""
        self.progress_bar.update(progress)